home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / UTILITY / INTER29A.ARJ / INTLIST.E < prev    next >
Text File  |  1992-02-06  |  19KB  |  678 lines

  1. /****************************************************************/
  2. /*    EEL code file for editing the Interrupt List        */
  3. /*                                */
  4. /*    Written by Ralf Brown                    */
  5. /*    LastEdit:  6 Feb 92                    */
  6. /*                                */
  7. /*  This EEL file adds the following keybindings:        */
  8. /*    Alt-N    add a new note to current entry or data struct  */
  9. /*    Alt-S    insert SeeAlso: at start of line        */
  10. /*    Alt-R    insert Return: at start of line            */
  11. /*    F11    insert a blank separator line            */
  12. /*    ^F11    create Format of: header            */
  13. /*    +F11    create Values for: header            */
  14. /*    Alt-F11 create Call with: header            */
  15. /*    F12    add the interrupt number to the separator line    */
  16. /*        preceding the current entry            */
  17. /*    ^F12    jump to a specified entry            */
  18. /*                                */
  19. /*  Other:                            */
  20. /*    adds intlist-mode for .LST and .1ST files        */
  21. /*    switches current buffer into intlist-mode on loading    */
  22. /****************************************************************/
  23.  
  24. #include "eel.h"
  25.  
  26. keytable intlist_tab ;            /* key table for IntList mode */
  27.  
  28. /*=============================================================*/
  29. /*=============================================================*/
  30.  
  31. int empty_line()
  32. {
  33.    return (character(point-1) == '\n' && character(point) == '\n') ;
  34. }
  35.  
  36. /*=============================================================*/
  37. /* Add "SeeAlso: " to the beginning of the current line unless */
  38. /* it is already present                       */
  39. /*=============================================================*/
  40.  
  41. command see_also() on intlist_tab[ALT('s')]
  42. {
  43.    int start = point ;
  44.    
  45.    to_begin_line() ;
  46.    if (parse_string(1,"SeeAlso: ",NULL) == 0)
  47.       stuff("SeeAlso: ") ;
  48.    else
  49.       point = start ;
  50. }
  51.  
  52. /*=============================================================*/
  53. /*=============================================================*/
  54.  
  55. int is_separator_line()
  56. {
  57.    if (empty_line() || parse_string(1,"--------",NULL))
  58.       return 1 ;
  59.    else 
  60.       return 0 ;
  61. }
  62.  
  63. /*=============================================================*/
  64. /* Add "Note: " section to the current entry; change an           */
  65. /* existing Note: to Notes: and position at end of Note:       */
  66. /* section.                               */
  67. /*=============================================================*/
  68.  
  69. command note() on intlist_tab[ALT('n')]
  70. {
  71.    int len ;
  72.    int done = 0 ;
  73.    
  74.    to_begin_line() ;
  75.    while (!empty_line() && !parse_string(1,"\n--------",NULL))
  76.       if (!nl_reverse())
  77.      break ;
  78.    point++ ;                /* skip the newline */
  79.    nl_forward() ;            /* advance a line */
  80.    while (!is_separator_line() && !parse_string(1,"Notes*:\t",NULL) &&
  81.           !parse_string(1,"SeeAlso:",NULL))
  82.       if (!nl_forward())
  83.      break ;
  84.    len = parse_string(1,"Notes*:\t",NULL) ;
  85.    if (len == 0) /* no notes section */
  86.       stuff("Note:") ;
  87.    else
  88.       {
  89.       if (len == 6)  /* Note: */
  90.      {
  91.      point += 4 ;
  92.      stuff("s") ;    /* change it to Notes: */
  93.      }
  94.       while (!is_separator_line() && !parse_string(1,"SeeAlso:",NULL))
  95.      nl_forward() ;
  96.       }
  97.    stuff("\t\n") ;
  98.    point-- ;
  99. }
  100.  
  101. /*=============================================================*/
  102. /* Insert "Return: " at the beginning of the current line, if  */
  103. /* not already present                           */
  104. /*=============================================================*/
  105.  
  106. command returns() on intlist_tab[ALT('r')]
  107. {
  108.    int len ;
  109.    int start = point ;
  110.    
  111.    to_begin_line() ;
  112.    if (parse_string(1,"Return: ",NULL) == 0)
  113.       stuff("Return: ") ;
  114.    else
  115.       point = start ;
  116. }
  117.  
  118. /*=============================================================*/
  119. /* insert a line of dashes prior to the current cursor line    */
  120. /*=============================================================*/
  121.  
  122. command separator_line() on intlist_tab[FKEY(11)]
  123. {
  124.    int i ;
  125.  
  126.    to_begin_line() ;
  127.    for (i = 0 ; i < 45 ; i++)
  128.       insert('-') ;
  129.    insert('\n') ;
  130. }
  131.  
  132. /*=============================================================*/
  133. /* type the name of a structure, then invoke this function     */
  134. /* to create the "Format of X:" and "Offset Size Descr" lines  */
  135. /*=============================================================*/
  136.  
  137. command structure_header() on intlist_tab[FCTRL(11)]
  138. {
  139.    to_begin_line() ;
  140.    stuff("Format of ") ;
  141.    to_end_line() ;
  142.    stuff(":\nOffset\tSize\tDescription\n 00h\t") ;
  143. }
  144.  
  145. /*=============================================================*/
  146. /* Turn the current line into the header for a "Values of"     */
  147. /* section                               */
  148. /*=============================================================*/
  149.  
  150. command value_header() on intlist_tab[FSHIFT(11)]
  151. {
  152.    int start = point ;
  153.    
  154.    to_begin_line() ;
  155.    if (parse_string(1,"Values for ",NULL) == 0)
  156.       {
  157.       stuff("Values for ") ;
  158.       to_end_line() ;
  159.       stuff(":\n ") ;
  160.       }
  161.    else
  162.       point = start ;
  163. }
  164.  
  165. /*=============================================================*/
  166. /* Turn the current line into the header of a "Call with"      */
  167. /* section                               */
  168. /*=============================================================*/
  169.  
  170. command call_with_header() on intlist_tab[FALT(11)]
  171. {
  172.    int start = point ;
  173.    
  174.    to_begin_line() ;
  175.    if (parse_string(1,"Call ",NULL) == 0)
  176.       {
  177.       stuff("Call ") ;
  178.       to_end_line() ;
  179.       stuff("with:\n") ;
  180.       }
  181.    else
  182.       point = start ;
  183. }
  184.  
  185. /*=============================================================*/
  186. /*=============================================================*/
  187.  
  188. char grab_entry_number(func_num)
  189. char *func_num ;
  190. {
  191.    char c ;
  192.    
  193.    strcpy(func_num,"------------") ;    /* 12 dashes */
  194.    point++ ;                /* go to first char of separator line */
  195.    nl_forward() ;            /* go to first line of entry */
  196.    if (parse_string(1,"INT ",NULL) == 0)
  197.       return 0 ;            /* not an interrupt entry, so return */
  198.    point += 4 ;                /* skip the "INT " */
  199.    func_num[0] = curchar() ;        /* grab the interrupt number */
  200.    point++ ;
  201.    func_num[1] = curchar() ;
  202.    nl_forward() ;            /* skip to second line of entry */
  203.    if (parse_string(1,"[ \t]*A[LHX][ \t]=[ \t][0-9A-F][0-9A-F]+h",NULL))
  204.       {
  205.       re_search(1,"[ \t]*A") ;
  206.       c = curchar() ;
  207.       point += 4 ;            /* skip ch and " = " */
  208.       if (c != 'L')
  209.      {
  210.      grab(point,point+((c=='X')?4:2),func_num+2) ;
  211.      func_num[(c=='H')?4:6] = '-' ;    /* grab() stuck a NUL into the string */
  212.      nl_forward() ;            /* skip to third line of entry */
  213.      }
  214.       else /* c == 'L' */
  215.      {
  216.      func_num[6] = 'A' ;
  217.      func_num[7] = 'L' ;
  218.      grab(point,point+2,func_num+8) ;
  219.      func_num[10] = '-' ;        /* grab() stuck a NUL into the string */
  220.      return 1 ;
  221.      }
  222.       }
  223.    if (parse_string(1,"[ \t]*[BCDES][HILPSX] = [0-9A-F][0-9A-F]+h",NULL))
  224.       {
  225.       re_search(1,"[ \t]*") ;
  226.       func_num[6] = curchar() ;
  227.       point++ ;
  228.       func_num[7] = c = curchar() ;
  229.       point += 4 ;            /* skip curchar and " = " */
  230.       if (c == 'H' || c == 'L')
  231.      {
  232.      grab(point,point+2,func_num+8) ;
  233.      func_num[10] = '-' ;        /* grab() stuck a NUL into the string */
  234.      }
  235.       else /* c == 'X' || c == 'I' || c == 'P' || c == 'S' */
  236.      grab(point,point+4,func_num+8) ;
  237.       }
  238.    return 1 ;                /* successful and have func number */
  239. }
  240.  
  241. /*=============================================================*/
  242. /* Put the interrupt and function number into the separator    */
  243. /* line just above the intlist entry preceding the cursor pos  */
  244. /*=============================================================*/
  245.  
  246. int number_one_int()
  247. {
  248.    char func_num[13] ;            /* 2->int, 4->AX, 6->extra reg, NUL */
  249.    int oldpoint ;
  250.    
  251.    while (search(-1,"\n--------"))    /* find previous separator line */
  252.       {
  253.       oldpoint = point ;
  254.       if (grab_entry_number(func_num))    /* does it belong to an intlist entry? */
  255.      {                /*   if yes, success, else try again */
  256.      point = oldpoint + 11 ;    /* skip NL and first ten dashes */
  257.      delete(point,point+12) ;    /* replace 12 dashes by the function */
  258.      stuff(func_num) ;        /*   number and extra register */
  259.      point = oldpoint ;        /* back to start of line, allowing repeat */
  260.      return 1 ;
  261.      }
  262.       point = oldpoint ;
  263.       }
  264.    return 0 ;                /* if we get here, we failed */
  265. }
  266.  
  267. /*=============================================================*/
  268. /* Put the interrupt and function number into the separator    */
  269. /* line just above one or more intlist entries preceding the   */
  270. /* current cursor position, letting user know of progress      */
  271. /*=============================================================*/
  272.  
  273. command number_int() on intlist_tab[FKEY(12)]
  274. {
  275.    int i, hit_top = 0 ;
  276.    
  277.    for (i = 0 ; i < iter ; i++)
  278.       {
  279.       if (!number_one_int())
  280.      {
  281.      hit_top = 1 ;
  282.      say("No prior entry.") ;
  283.      break ;
  284.      }
  285.       if (((i+1) % 100) == 0)
  286.      say("%d...",i+1) ;
  287.       }
  288.    if (iter > 1 && !hit_top)
  289.       say("Done.") ;
  290.    iter = 1 ;
  291. }
  292.  
  293. /*=============================================================*/
  294. /*=============================================================*/
  295.  
  296. int line_has_see_also()
  297. {
  298.    int start = point ;
  299.    int len ;
  300.    
  301.    to_begin_line() ;
  302.    if ((len = parse_string(1,".*%([sS]ee ",NULL)) != 0)
  303.       {
  304.       point += len ;        /* go to start of cross-reference */
  305.       point += parse_string(1,"also ",NULL) ;
  306.       if (parse_string(1,"INT [0-9A-F]",NULL) ||
  307.       parse_string(1,"A[XHL] =",NULL)
  308.      )
  309.      {
  310.      point++ ;        /* move into reference */
  311.      return 1 ;
  312.      }
  313.       }
  314.    return 0 ;
  315. }
  316.  
  317. /*=============================================================*/
  318. /*=============================================================*/
  319.  
  320. int grab_int_reference(ref)
  321. char *ref ;
  322. {
  323.    int begin, start = point ;
  324.    
  325.    re_search(-1,"[, \t\n]") ;    /* backup to start of reference */
  326.    if (curchar() == '\n')    /* start of line? */
  327.       re_search(1,":[ \t]") ;    /* skip the SeeAlso: */
  328.    else if (character(point-1) == 'T' && character(point-2) == 'N')
  329.       point -= 3 ;
  330.    else
  331.       point++ ;            /* back to start of reference */
  332.    begin = point ;
  333.    re_search(1,"[,\n\"]") ;    /* find end of INT-spec */
  334.    point-- ;
  335.    if (curchar() == '\"')    /* extra string at end of INT-spec? */
  336.       {
  337.       point++ ;
  338.       re_search(1,"[\"\n]") ;    /* if yes, run to end of line or string */
  339.       }
  340.    grab(begin,point,ref) ;
  341.    point = start ;
  342.    return 0 ;
  343. }
  344.  
  345. /*=============================================================*/
  346. /*=============================================================*/
  347.  
  348. int parse_int_name(entry_name,id,extra_string)
  349. char *entry_name, *id, *extra_string ;
  350. {
  351.    int start = point ;
  352.    int i ;
  353.    char def_int[3] ;
  354.    char c, *last ;
  355.  
  356.    for (i = strlen(entry_name)-1 ; i >= 0 ; i--)
  357.       entry_name[i] = toupper(entry_name[i]) ;
  358.    strcpy(id,"------------") ;
  359.    if (strncmp(entry_name,"INT ",4) == 0)
  360.       {
  361.       id[0] = entry_name[4] ;
  362.       id[1] = entry_name[5] ;
  363.       entry_name += 6 ;
  364.       if (entry_name[0] == '/')
  365.      entry_name++ ;
  366.       }
  367.    else if (search(-1,"\n----------"))
  368.       {
  369.       id[0] = character(point+11) ;
  370.       id[1] = character(point+12) ;
  371.       }
  372.    point = start ;
  373.    if (entry_name[0] == 'A' && (entry_name[1] == 'X' || entry_name[1] == 'H'))
  374.       {
  375.       c = entry_name[1] ;
  376.       entry_name += 2 ;
  377.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  378.      entry_name++ ;
  379.       if (entry_name[0] == '=')
  380.      entry_name++ ;
  381.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  382.      entry_name++ ;
  383.       id[2] = entry_name[0] ;
  384.       id[3] = entry_name[1] ;
  385.       if (c == 'X')
  386.      {
  387.      id[4] = entry_name[2] ;
  388.      id[5] = entry_name[3] ;
  389.      entry_name += 4 ;
  390.      }
  391.       else
  392.      entry_name += 2 ;
  393.       if (entry_name[0] == 'H')
  394.      entry_name++ ;
  395.       if (entry_name[0] == '/')
  396.      entry_name++ ;
  397.       }
  398.    if (index("ABCDES",entry_name[0]) && index("HILPSX",entry_name[1]))
  399.       {
  400.       id[6] = entry_name[0] ;
  401.       c = id[7] = entry_name[1] ;
  402.       entry_name += 2 ;
  403.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  404.      entry_name++ ;
  405.       if (entry_name[0] == '=')
  406.      entry_name++ ;
  407.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  408.      entry_name++ ;
  409.       id[8] = entry_name[0] ;
  410.       id[9] = entry_name[1] ;
  411.       if (c != 'H' && c != 'L')
  412.      {
  413.      id[10] = entry_name[2] ;
  414.      id[11] = entry_name[3] ;
  415.      entry_name += 4 ;
  416.      }
  417.       else
  418.      entry_name += 2 ;
  419.       if (entry_name[0] == 'H')
  420.      entry_name++ ;
  421.       if (entry_name[0] == '/')
  422.      entry_name++ ;
  423.       }
  424.    if (entry_name[0] == '\"')
  425.       {
  426.       entry_name++ ;
  427.       strcpy(extra_string,entry_name) ;
  428.       last = index(extra_string,'\"') ;
  429.       if (last)
  430.      *last = '\0' ;
  431.       }
  432.    else
  433.       extra_string[0] = '\0' ;
  434.    return 0 ;
  435. }
  436.  
  437. /*=============================================================*/
  438. /*=============================================================*/
  439.  
  440. int hex2_to_int(c1,c2)
  441. char c1, c2 ;
  442. {
  443.    if (c1 >= '0' && c1 <= '9')
  444.       c1 -= '0' ;
  445.    else if (c1 >= 'A' && c1 <= 'F')
  446.       c1 = c1 - 'A' + 10 ;
  447.    else if (c1 >= 'a' && c1 <= 'f')
  448.       c1 = c1 - 'a' + 10 ;
  449.    else
  450.       return -1 ;
  451.    if (c2 >= '0' && c2 <= '9')
  452.       c2 -= '0' ;
  453.    else if (c2 >= 'A' && c2 <= 'F')
  454.       c2 = c2 - 'A' + 10 ;
  455.    else if (c2 >= 'a' && c2 <= 'f')
  456.       c2 = c2 - 'a' + 10 ;
  457.    else
  458.       return -1 ;
  459.    return 16*c1 + c2 ;
  460. }
  461.  
  462. /*=============================================================*/
  463. /*=============================================================*/
  464.  
  465. char hex_digit(val)
  466. int val ;
  467. {
  468.    if (val < 0)
  469.       return '-' ;
  470.    else if (val > 9)
  471.       return 'A' + val - 10 ;
  472.    else
  473.       return '0' + val ;
  474. }
  475.  
  476. /*=============================================================*/
  477. /*=============================================================*/
  478.  
  479. int scan_for_entry(entry,extra_str,first_entry)
  480. char *entry, *extra_str ;
  481. int *first_entry ;
  482. {
  483.    int ah, al, t1, t2, match, found ;
  484.    char buf[7] ;
  485.    
  486.    *first_entry = 0 ;
  487.    ah = hex2_to_int(entry[2],entry[3]) ;
  488.    while (1)
  489.       {
  490.       if (!search(1,"\n---------"))
  491.      return 0 ;    /* failed if hit end of file */
  492.       if (character(point+1) != entry[0] || character(point+2) != entry[1])
  493.      return 0 ;    /* failed if no longer on same interrupt */
  494.       t1 = hex2_to_int(character(point+3),character(point+4)) ;
  495.       if (t1 == ah)
  496.      break ;
  497.       else if (t1 > ah)
  498.      {
  499.      to_begin_line() ;
  500.      *first_entry = point ;
  501.      return 0 ;    /* no such entry */
  502.      }
  503.       }
  504.    nl_reverse() ;
  505.    *first_entry = point ;
  506.    found = 0 ;
  507.    al = hex2_to_int(entry[4],entry[5]) ;
  508.    while (1)
  509.       {
  510.       if (!search(1,"\n---------"))
  511.      return 0 ;    /* failed if hit end of file */
  512.       if (character(point+1) != entry[0] || character(point+2) != entry[1])
  513.      return 0 ;    /* failed if no longer on same interrupt */
  514.       t1 = hex2_to_int(character(point+3),character(point+4)) ;
  515.       if (t1 != ah)
  516.      return 0 ;    /* failed if no longer on same INT/AH combo */
  517.       t2 = hex2_to_int(character(point+5),character(point+6)) ;
  518.       if (t2 == al)
  519.      {
  520.      if (!found)
  521.         {
  522.         found = 1 ;
  523.         *first_entry = point ;
  524.         }
  525.      if (entry[6] != '-')
  526.         {
  527.         grab(point+7,point+12,buf) ;
  528.         match = strncmp(buf,entry+6,6) ;
  529.         if (match == 0)
  530.            {
  531.            *first_entry = point ;
  532.            break ;
  533.            }
  534.         else if (match > 0)
  535.            return 0 ;    /* no exact match, but return a partial match */
  536.         }
  537.      else
  538.         break ;
  539.      }
  540.       else if (t2 > al)
  541.      {
  542.      if (found)
  543.         break ;
  544.      else
  545.         {
  546.         to_begin_line() ;
  547.         *first_entry = point ;
  548.         return 0 ;    /* no such entry */
  549.         }
  550.      }
  551.       }
  552.    point = *first_entry ;    /* back to first matching entry */
  553.    
  554.    
  555.    return 1 ;            /* we were successful */
  556. }
  557.  
  558. /*=============================================================*/
  559. /*=============================================================*/
  560.  
  561. int goto_entry(entry_name)
  562. char *entry_name ;
  563. {
  564.    char int_id[13], extra_string[60] ;
  565.    int start = point, first_entry ;
  566.    int int_num, curr_int ;
  567.    char search_str[22] ;
  568.    char line_buf[90] ;
  569.    
  570.    parse_int_name(entry_name,int_id,extra_string) ;
  571.    int_num = hex2_to_int(int_id[0],int_id[1]) ;
  572.    if (search(-1,"\n----------"))
  573.       {
  574.       if (character(point+11) == '-')
  575.      curr_int = -1 ;
  576.       else
  577.      curr_int = hex2_to_int(character(point+11),character(point+12)) ;
  578.       if (int_num <= 0)
  579.      point = 0 ;        /* go to top of file */
  580.       else
  581.      {
  582.      if (curr_int < 0)
  583.         point = 0 ;        /* go to top of file */
  584.      strcpy(search_str,"----------") ;
  585.      search_str[10] = hex_digit((int_num-1) / 16) ;
  586.      search_str[11] = hex_digit((int_num-1) % 16) ;
  587.      search_str[12] = '\0' ;
  588.      search( (int_num<=curr_int)?-1:1, search_str) ;
  589.      to_begin_line() ;
  590.      }
  591.       }
  592.    else
  593.       point = 0 ;
  594.    if (!scan_for_entry(int_id,extra_string,&first_entry))
  595.       {
  596.       say("%s not found.",entry_name) ;
  597.       if (first_entry)
  598.      {
  599.      mark = start ;
  600.      point = first_entry ;
  601.      }
  602.       else
  603.      point = start ;
  604.       }
  605.    if (has_arg)
  606.      iter = 1 ;                /* don't search repeatedly */
  607.    return 0 ;
  608. }
  609.  
  610. /*=============================================================*/
  611. /*=============================================================*/
  612.  
  613. command goto_int() on intlist_tab[FCTRL(12)]
  614. {
  615.    char entry_name[60], def_entry[60] ;
  616.    int start = point ;
  617.  
  618.    to_begin_line() ;
  619.    if (parse_string(1,"SeeAlso: ",NULL) != 0)
  620.       {
  621.       point += 9 ;        /* skip the SeeAlso: */
  622.       if (point < start)    /* if we were originally to the right of     */
  623.      point = start ;    /* current position, go back to original pos */
  624.       grab_int_reference(def_entry) ;
  625.       get_strdef(entry_name,"Goto Interrupt",def_entry) ;
  626.       }
  627.    else if (line_has_see_also())
  628.       {
  629.       grab_int_reference(def_entry) ;
  630.       get_strdef(entry_name,"Goto Interrupt",def_entry) ;
  631.       }
  632.    else
  633.       get_string(entry_name,"Goto Interrupt: ") ;
  634.    point = start ;
  635.    goto_entry(entry_name) ;
  636.    if (has_arg)
  637.       iter = 1 ;
  638. }
  639.  
  640. /*=============================================================*/
  641. /* Put the current buffer into IntList major mode           */
  642. /*=============================================================*/
  643.  
  644. command intlist_mode()
  645. {
  646.    mode_keys = intlist_tab ;
  647.    intlist_tab[')'] = intlist_tab[']'] = (short) show_matching_delimiter;
  648.    delete_hacking_tabs = 0 ;
  649.    major_mode = strsave("IntList") ;
  650.    make_mode() ;
  651.    auto_indent = 0 ;
  652.    margin_right = 79 ;
  653.    want_backups = 1 ;
  654. }
  655.  
  656. when_loading()
  657. {
  658.    char *curbuf ;
  659.  
  660.    want_backups = want_backups.default = 1 ;
  661.    strcpy(backup_name,"%pbak/%b%e") ;
  662.    one_window() ;
  663.    intlist_mode() ;
  664.    if (exist("interrup.1st"))
  665.       {
  666.       curbuf = bufname ;
  667.       bufname = "interrup.1st" ;
  668.       intlist_mode() ;
  669.       bufname = curbuf ;
  670.       }
  671. }
  672.  
  673. /*=============================================================*/
  674. /* automagically switch into interrupt list mode on .LST and .1ST files */
  675.  
  676. suffix_lst()   { intlist_mode(); }
  677. suffix_1st()   { intlist_mode(); }
  678.